home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Sample.bin / OpenlookButton.java < prev    next >
Text File  |  1998-09-15  |  7KB  |  247 lines

  1. /*
  2.  * @(#)OpenlookButton.java    1.1 98/07/18
  3.  *
  4.  * Copyright (c) 1995-1997 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  */
  7.  
  8. package actual;
  9.  
  10. import java.applet.*;
  11. import java.lang.*;
  12. import java.util.*;
  13. import java.awt.*;
  14. import java.awt.event.*;
  15.  
  16. /**
  17.  * OpenlookButton - a class that produces a lightweight button.
  18.  *
  19.  * Lightweight components can have "transparent" areas, meaning that
  20.  * you can see the background of the container behind them.
  21.  *
  22.  */
  23. public class OpenlookButton extends Component {
  24.  
  25.   static int capWidth = 20;          // The width of the Button's endcap
  26.   String label;                      // The Button's text
  27.   protected boolean pressed = false; // true if the button is detented.
  28.   ActionListener actionListener;     // Post action events to listeners
  29.   
  30.   
  31.   /**
  32.    * Constructs an OpenlookButton with no label.
  33.    */
  34.   public OpenlookButton() {
  35.       this("");
  36.   }
  37.  
  38.   /**
  39.    * Constructs an OpenlookButton with the specified label.
  40.    * @param label the label of the button
  41.    */
  42.   public OpenlookButton(String label) {
  43.       this.label = label;
  44.       enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  45.   }
  46.  
  47.   /**
  48.    * gets the label
  49.    * @see setLabel
  50.    */
  51.   public String getLabel() {
  52.       return label;
  53.   }
  54.   
  55.   /**
  56.    * sets the label
  57.    * @see getLabel
  58.    */
  59.   public void setLabel(String label) {
  60.       this.label = label;
  61.       invalidate();
  62.       repaint();
  63.   }
  64.   
  65.   /**
  66.    * paints the button
  67.    */
  68.   public void paint(Graphics g) {
  69.       int width = getSize().width - 1;
  70.       int height = getSize().height - 1;
  71.  
  72.       Color interior;
  73.       Color highlight1;
  74.       Color highlight2;
  75.       
  76.       interior = getBackground();
  77.  
  78.       // ***** determine what colors to use
  79.       if(pressed) {
  80.       highlight1 = interior.darker();
  81.       highlight2 = interior.brighter();
  82.       } else {
  83.       highlight1 = interior.brighter();
  84.       highlight2 = interior.darker();
  85.       }
  86.  
  87.       // ***** paint the interior of the button
  88.       g.setColor(interior);
  89.       // left cap
  90.       g.fillArc(0, 0,                 // start
  91.         capWidth, height,            // size
  92.         90, 180);            // angle
  93.  
  94.       // right cap
  95.       g.fillArc(width - capWidth, 0,        // start
  96.         capWidth, height,           // size
  97.         270, 180);            // angle
  98.  
  99.       // inner rectangle
  100.       g.fillRect(capWidth/2, 0, width - capWidth, height);
  101.       
  102.  
  103.       // ***** highlight the perimeter of the button
  104.       // draw upper and lower highlight lines
  105.       g.setColor(highlight1);
  106.       g.drawLine(capWidth/2, 0, width - capWidth/2, 0);
  107.       g.setColor(highlight2);
  108.       g.drawLine(capWidth/2, height, width - capWidth/2, height);
  109.  
  110.       // upper arc left cap
  111.       g.setColor(highlight1);
  112.       g.drawArc(0, 0,                       // start
  113.                 capWidth, height,           // size
  114.                 90, 180-40                  // angle
  115.       );
  116.  
  117.       // lower arc left cap
  118.       g.setColor(highlight2);
  119.       g.drawArc(0, 0,                       // start
  120.                 capWidth, height,           // size
  121.                 270-40, 40                  // angle
  122.       );
  123.  
  124.       // upper arc right cap
  125.       g.setColor(highlight1);
  126.       g.drawArc(width - capWidth, 0,        // start
  127.                 capWidth, height,           // size
  128.                 90-40, 40                   // angle
  129.       );
  130.  
  131.       // lower arc right cap
  132.       g.setColor(highlight2);
  133.       g.drawArc(width - capWidth, 0,        // start
  134.                 capWidth, height,           // size
  135.                 270, 180-40                 // angle
  136.       );
  137.  
  138.       // ***** draw the label centered in the button
  139.       Font f = getFont();
  140.       if(f != null) {
  141.       FontMetrics fm = getFontMetrics(getFont());
  142.       g.setColor(getForeground());
  143.       g.drawString(label,
  144.                width/2 - fm.stringWidth(label)/2,
  145.                height/2 + fm.getHeight()/2 - fm.getMaxDescent()
  146.       );
  147.       }
  148.   }
  149.   
  150.   /**
  151.    * The preferred size of the button. 
  152.    */
  153.   public Dimension getPreferredSize() {
  154.       Font f = getFont();
  155.       if(f != null) {
  156.       FontMetrics fm = getFontMetrics(getFont());
  157.       return new Dimension(fm.stringWidth(label) + capWidth*2,
  158.                    fm.getHeight() + 10);
  159.       } else {
  160.       return new Dimension(100, 50);
  161.       }
  162.   }
  163.   
  164.   /**
  165.    * The minimum size of the button. 
  166.    */
  167.   public Dimension getMinimumSize() {
  168.       return new Dimension(100, 50);
  169.   }
  170.  
  171.   /**
  172.    * Adds the specified action listener to receive action events
  173.    * from this button.
  174.    * @param listener the action listener
  175.    */
  176.    public void addActionListener(ActionListener listener) {
  177.        actionListener = AWTEventMulticaster.add(actionListener, listener);
  178.        enableEvents(AWTEvent.MOUSE_EVENT_MASK);
  179.    }
  180.  
  181.    /**
  182.     * Removes the specified action listener so it no longer receives
  183.     * action events from this button.
  184.     * @param listener the action listener
  185.     */
  186.    public void removeActionListener(ActionListener listener) {
  187.        actionListener = AWTEventMulticaster.remove(actionListener, listener);
  188.    }
  189.  
  190.  
  191.    /**
  192.     * Paints the button and sends an action event to all listeners.
  193.     */
  194.    public void processMouseEvent(MouseEvent e) {
  195.        Graphics g;
  196.        switch(e.getID()) {
  197.           case MouseEvent.MOUSE_PRESSED:
  198.             // render myself inverted....
  199.             pressed = true;
  200.     
  201.         // Repaint might flicker a bit. To avoid this, you can use
  202.         // double buffering (see the Gauge example).
  203.         repaint();
  204.             break;
  205.           case MouseEvent.MOUSE_RELEASED:
  206.             if(actionListener != null) {
  207.                actionListener.actionPerformed(new ActionEvent(
  208.                    this, ActionEvent.ACTION_PERFORMED, label));
  209.             }
  210.             // render myself normal again
  211.             if(pressed == true) {
  212.                 pressed = false;
  213.  
  214.             // Repaint might flicker a bit. To avoid this, you can use
  215.             // double buffering (see the Gauge example).
  216.         repaint();
  217.             }
  218.             break;
  219.           case MouseEvent.MOUSE_ENTERED:
  220.  
  221.             break;
  222.           case MouseEvent.MOUSE_EXITED:
  223.             if(pressed == true) {
  224.                 // Cancel! Don't send action event.
  225.                 pressed = false;
  226.  
  227.             // Repaint might flicker a bit. To avoid this, you can use
  228.             // double buffering (see the Gauge example).
  229.         repaint();
  230.  
  231.                 // Note: for a more complete button implementation,
  232.                 // you wouldn't want to cancel at this point, but
  233.                 // rather detect when the mouse re-entered, and
  234.                 // re-highlight the button. There are a few state
  235.                 // issues that that you need to handle, which we leave
  236.                 // this an an excercise for the reader (I always
  237.                 // wanted to say that!)
  238.             }
  239.             break;
  240.        }
  241.        super.processMouseEvent(e);
  242.    }
  243.  
  244.  
  245. }
  246.  
  247.